/**
 * Copyright (c) 2016-2020 https://github.com/zhaohuatai
 *
 * contact z_huatai@qq.com
 *  
 */
package org.zfes.snowy.base.dao.jdbc;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.sql.DataSource;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
import org.zfes.snowy.base.dao.enums.DataBaseType;
import org.zfes.snowy.base.dao.enums.QueryType;
import org.zfes.snowy.base.dao.params.ParamMap;
import org.zfes.snowy.core.data.DataSet;
import org.zfes.snowy.core.exceptions.AppRuntimeException;
import org.zfes.snowy.core.util.ZStrUtil;
public class SnowyJdbcBaseDaoImpl extends NamedParameterJdbcDaoSupport implements ISnowyJdbcBaseDao{
	
	private DataBaseType dbType;
	
	public SnowyJdbcBaseDaoImpl(DataBaseType databasetype,DataSource dataSource) {
		this.dbType=databasetype;
		setDataSource(dataSource);
	}
	
	@SuppressWarnings("unchecked")
	public DataSet loadDataSet(String queryStr,ParamMap params){
		if(queryStr==null||!(queryStr.contains("@from")||queryStr.contains("@FROM"))){
			throw new AppRuntimeException("查询语句错误,或未找到[@from]标识");
		}
		QueryType queryType=(params.getQueryType()==null?QueryType.S_O_C:params.getQueryType());
		
		Long count=0L;
		List<Map<String, Object>> list=new ArrayList<>();
		queryStr=queryStr.replace("@FROM", "@from");
		String queryCountStr=" select count(1) from "+ZStrUtil.substringAfter(queryStr, "@from");
		queryStr=queryStr.replace("@from", "from");
		 switch (queryType) { 
		 	case S_O_C:{
		 				Object[] formatParam=JdbcDaoUtil.genSQL(dbType,params);
						queryStr = MessageFormat.format(dbType.getValue(), formatParam);
				 		list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
				 		count=getNamedParameterJdbcTemplate().queryForObject(queryCountStr, params,Long.class);
			 		}
	            break; 
		 	case S_O_NC:{
		 				Object[] formatParam=JdbcDaoUtil.genSQL(dbType,params);
						queryStr = MessageFormat.format(dbType.getValue(), formatParam);
				 		list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
			 		}
	            break;
		 	case S_NO_C:{
			 			list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
			 			count=getNamedParameterJdbcTemplate().queryForObject(queryCountStr, params,Long.class);
		 		}
	            break;
		 	case S_NO_NC: {
		 				list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
		 		}
	            break;
	        default:
	        	throw new AppRuntimeException("未知类型的查询") ;
		 }
		 return new DataSet(count,(List<Map<String, Object>>) (list==null?Collections.emptyList():list));
	}

	@Override
	public long queryCount(String CountSql,Map<String,Object> params) {
		Long count=0L;
		count=getNamedParameterJdbcTemplate().queryForObject(CountSql, params,Long.class);
		return count;
	}

	@Override
	public int update(String updateStr,  Map<String,Object> params) {
		return getNamedParameterJdbcTemplate().update(updateStr, params);
	}
	@Override
	public int[] batchUpdate(String batchUpdateSql, Map<String,?>[] paramObject) {//Map<String,?>[]
		return getNamedParameterJdbcTemplate().batchUpdate(batchUpdateSql, paramObject);
	}
	
	@Override
	public int delete(String deleteSql, Map<String,Object> params){
		return update(deleteSql, params);
	}
	@Override
	public int[] batchDelete(String batchDeleteSql, Map<String,?>[] params){
		return batchUpdate(batchDeleteSql, params);
	}

	@Override
	public int insert(String inserSql, Map<String,Object> params) {
		return update(inserSql, params);
	}
	@Override
	public int[] batchInsert(String batchInsertSql,Map<String,?>[] params) {
		return getNamedParameterJdbcTemplate().batchUpdate(batchInsertSql, params);
	}

	
	@SuppressWarnings("unchecked")
	@Override
	public List<Map<String, Object>> queryMapList(String queryStr, Map<String,Object> params) {
		List<Map<String, Object>> list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
		return (List<Map<String, Object>>) (list==null?Collections.emptyList():list);
	}

	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Optional<Object> queryOneObject(String querySQL, Map<String,Object> params,Class<?> clazz) {
		Object obj =null;
		try{
			 obj = getNamedParameterJdbcTemplate().queryForObject(querySQL, params,new BeanPropertyRowMapper(clazz));
		}catch(EmptyResultDataAccessException e){
			return Optional.empty();
		}
		return Optional.ofNullable(obj);
		
	}
	
	@Override
	public Map<String,Object>  queryOneRowByUnque(String queryStr,  Map<String,Object> params) {
		List<Map<String, Object>> list=getNamedParameterJdbcTemplate().queryForList(queryStr, params);
		if(list!=null&&!list.isEmpty()){
			return list.get(0);
		}
		return null;
	}
	@Override
	public List<String> queryStrResList(String querySQL,Map<String,Object> params) {
		List<String> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, String.class);
		return list;
	}
	public Optional<String> queryUniqueStr(String querySQL,Map<String,Object> params){
		List<String> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, String.class);
		if(list==null||list.isEmpty()){
			return Optional.empty();
		}
		return Optional.of(list.get(0));
	}
	@Override
	 public List<Long> queryLongList(String querySQL,Map<String,Object> params){
		List<Long> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Long.class);
		return list;
	 }
	@Override
	 public Optional<Long> queryUniqueLong(String querySQL,Map<String,Object> params){
		List<Long> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Long.class);
		if(list==null||list.isEmpty()){
			return Optional.empty();
		}
		return Optional.of(list.get(0));
	 }
	@Override
	 public List<Integer> queryIntegerList(String querySQL,Map<String,Object> params){
		List<Integer> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Integer.class);
		return list;
	 }
	@Override
	 public Optional<Integer> queryUniqueInteger(String querySQL,Map<String,Object> params){
		List<Integer> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Integer.class);
		if(list==null||list.isEmpty()){
			return Optional.empty();
		}
		return Optional.of(list.get(0));
	 }
	 @Override
	 public List<Short> queryShortList(String querySQL,Map<String,Object> params){
		List<Short> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Short.class);
		return list;
	 }
	@Override
	 public List<Byte> queryByteList(String querySQL,Map<String,Object> params){
		List<Byte> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Byte.class);
		return list;
	 }
	@Override
	 public List<Float> queryFloatList(String querySQL,Map<String,Object> params){
		List<Float> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Float.class);
		return list;
	 }
	@Override
	 public List<Double> queryDoubleList(String querySQL,Map<String,Object> params){
		List<Double> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Double.class);
		return list;
	 }
	@Override
	 public List<Boolean> queryBooleanList(String querySQL,Map<String,Object> params){
		List<Boolean> list=getNamedParameterJdbcTemplate().queryForList(querySQL, params, Boolean.class);
		return list;
	 }

	
	
}
